package gui.tab;

import java.rmi.RemoteException;
import java.util.Enumeration;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;

import gui.TuristAssistant;
import gui.dialog.BlogItemComposite;
import gui.dialog.ShowBlogDialog;
import gui.pop.BlogPopupMenu;

import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;

import org.example.www.webBlogService.Blog;

import com.cloudgarden.resource.SWTResourceManager;

/**
 * Solapa correspondiente al trabajo con Blogs.
 * 
 * @author Gonzalo Maso Talou
 * 
 */
public class BlogCompositeTab extends org.eclipse.swt.widgets.Composite
		implements Observer {

	{
		// Register as a resource user - SWTResourceManager will
		// handle the obtaining and disposing of resources
		SWTResourceManager.registerResourceUser(this);
	}

	private ScrolledComposite blogsListComposite;
	private BlogPopupMenu blogPopup;
	private Composite dataBlogComposite;
	private Button enterButton;
	private StyledText blogDescriptionLabel;
	private Composite imageComposite;
	private Composite blogListContainer;

	/**
	 * Items que representan a los {@link Blog} cargados.
	 */
	private Vector<BlogItemComposite> items = new Vector<BlogItemComposite>();
	/**
	 * Representa al {@link BlogItemCOmposite} seleccionado.
	 */
	private BlogItemComposite active = null;

	public BlogCompositeTab(org.eclipse.swt.widgets.Composite parent, int style) {
		super(parent, style);
		initGUI();
		TuristAssistant.blogUpdater.addObserver(this);
	}

	private void initGUI() {
		try {
			GridLayout thisLayout = new GridLayout();
			thisLayout.numColumns = 2;
			this.setLayout(thisLayout);
			this.setSize(397, 252);
			{
				blogsListComposite = new ScrolledComposite(this, SWT.H_SCROLL
						| SWT.V_SCROLL | SWT.BORDER);
				GridLayout blogsListCompositeLayout = new GridLayout();
				blogsListCompositeLayout.makeColumnsEqualWidth = true;
				blogsListCompositeLayout.marginHeight = 0;
				blogsListCompositeLayout.marginWidth = 0;
				blogsListComposite.setLayout(blogsListCompositeLayout);
				GridData blogsListCompositeLData = new GridData();
				blogsListCompositeLData.verticalAlignment = GridData.FILL;
				blogsListCompositeLData.grabExcessVerticalSpace = true;
				blogsListCompositeLData.grabExcessHorizontalSpace = true;
				blogsListCompositeLData.horizontalAlignment = GridData.FILL;
				blogsListComposite.setLayoutData(blogsListCompositeLData);
				{
					blogListContainer = new Composite(blogsListComposite,
							SWT.NONE);
					blogsListComposite.setContent(blogListContainer);
					GridLayout cLayout = new GridLayout();
					cLayout.makeColumnsEqualWidth = true;
					cLayout.marginWidth = 0;
					cLayout.marginHeight = 0;
					blogListContainer.setLayout(cLayout);

					GridData cLData = new GridData();
					cLData.grabExcessHorizontalSpace = true;
					cLData.grabExcessVerticalSpace = true;
					cLData.horizontalAlignment = GridData.FILL;
					cLData.verticalAlignment = GridData.FILL;
					blogListContainer.setLayoutData(cLData);

					blogsListComposite.setContent(blogListContainer);
					blogsListComposite.setExpandHorizontal(true);
					blogsListComposite.setExpandVertical(true);
					blogsListComposite.setMinSize(blogListContainer
							.computeSize(SWT.DEFAULT, SWT.DEFAULT));
					blogsListComposite.setShowFocusedControl(true);

				}

			}
			{
				dataBlogComposite = new Composite(this, SWT.NONE);
				GridLayout dataBlogCompositeLayout = new GridLayout();
				dataBlogCompositeLayout.makeColumnsEqualWidth = true;
				dataBlogComposite.setLayout(dataBlogCompositeLayout);
				GridData dataBlogCompositeLData = new GridData();
				dataBlogCompositeLData.verticalAlignment = GridData.FILL;
				dataBlogCompositeLData.horizontalAlignment = GridData.END;
				dataBlogCompositeLData.widthHint = 195;
				dataBlogComposite.setLayoutData(dataBlogCompositeLData);
				{
					imageComposite = new Composite(dataBlogComposite, SWT.NONE);
					GridLayout imageCompositeLayout = new GridLayout();
					imageCompositeLayout.makeColumnsEqualWidth = true;
					GridData imageCompositeLData = new GridData();
					imageCompositeLData.verticalAlignment = GridData.BEGINNING;
					imageCompositeLData.horizontalAlignment = GridData.FILL;
					imageCompositeLData.grabExcessHorizontalSpace = true;
					imageCompositeLData.heightHint = 170;
					imageComposite.setLayoutData(imageCompositeLData);
					imageComposite.setLayout(imageCompositeLayout);
					imageComposite.setSize(185, 170);
				}
				{
					GridData blogDescriptionLabelLData = new GridData();
					blogDescriptionLabelLData.horizontalAlignment = GridData.FILL;
					blogDescriptionLabelLData.grabExcessHorizontalSpace = true;
					blogDescriptionLabelLData.verticalAlignment = GridData.FILL;
					blogDescriptionLabelLData.grabExcessVerticalSpace = true;
					blogDescriptionLabel = new StyledText(dataBlogComposite,
							SWT.WRAP | SWT.BORDER | SWT.V_SCROLL);
					blogDescriptionLabel.setVisible(false);
					blogDescriptionLabel
							.setLayoutData(blogDescriptionLabelLData);
					blogDescriptionLabel.setEditable(false);
				}
				{
					enterButton = new Button(dataBlogComposite, SWT.PUSH
							| SWT.CENTER);
					enterButton.setText("Enter to the Blog");
					GridData enterButtonLData = new GridData();
					enterButtonLData.verticalAlignment = GridData.END;
					enterButtonLData.horizontalAlignment = GridData.FILL;
					enterButtonLData.grabExcessHorizontalSpace = true;
					enterButton.setLayoutData(enterButtonLData);
					enterButton.addMouseListener(new MouseAdapter() {
						@Override
						public void mouseUp(MouseEvent evt) {
							enterButtonMouseUp(evt);
						}
					});
					enterButton.setEnabled(false);
				}
			}
			{
				blogPopup = new BlogPopupMenu(getShell(), SWT.POP_UP);
				blogPopup.setBoss(this);
			}
			this.layout();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Agrega un nuevo {@link Blog} a la interfaz.
	 * 
	 * @param blog
	 *            {@link Blog} a agregar.
	 */
	public void addBlogItem(Blog blog) {
		GridData itemLData = new GridData();
		itemLData.verticalAlignment = GridData.BEGINNING;
		itemLData.grabExcessHorizontalSpace = true;
		itemLData.horizontalAlignment = GridData.FILL;
		itemLData.heightHint = 110;
		BlogItemComposite item = new BlogItemComposite(blogListContainer,
				SWT.NONE, blog, this);
		item.setLayoutData(itemLData);

		blogsListComposite.setExpandHorizontal(true);
		blogsListComposite.setExpandVertical(true);
		blogsListComposite.setMinSize(blogListContainer.computeSize(
				SWT.DEFAULT, SWT.DEFAULT));
		blogsListComposite.setShowFocusedControl(true);

		items.add(item);
	}

	/**
	 * Establece un {@link BlogItemComposite} como seleccionado.
	 * 
	 * @param item
	 *            {@link BlogItemComposite} seleccionado.
	 */
	public void pressed(BlogItemComposite item) {
		if (active != null && !active.equals(item)) {
			active.release();
		}
		active = item;
		ImageData imageData = TuristAssistant.images.get(
				item.getBlog().getIdImage()).getImageData();
		imageComposite.setBackgroundImage(new Image(Display.getCurrent(),
				imageData.scaledTo(170 * (imageData.width / imageData.height),
						170)));

		blogDescriptionLabel.setText(item.getBlog().getDescription());
		blogDescriptionLabel.setVisible(true);
		blogDescriptionLabel.setLineAlignment(0, blogDescriptionLabel
				.getLineCount(), SWT.LEFT);
		blogDescriptionLabel.setLineJustify(0, blogDescriptionLabel
				.getLineCount(), true);

		enterButton.setEnabled(true);
	}

	public Composite getBlogListContainer() {
		return blogListContainer;
	}

	private void enterButtonMouseUp(MouseEvent evt) {
		ShowBlogDialog dialog = new ShowBlogDialog(this.getShell(), this
				.getStyle(), active.getBlog());
		dialog.open();
	}

	/**
	 * Actualiza los datos del {@link Blog} en la interfaz.
	 */
	@Override
	public void update(Observable arg0, Object arg1) {
		String idBlog = (String) arg1;
		boolean finish = false;
		for (Enumeration<BlogItemComposite> e = items.elements(); e
				.hasMoreElements()
				&& !finish;) {
			BlogItemComposite current = e.nextElement();
			if (current.getBlog().getIdBlog().equals(idBlog)) {
				try {
					current.setBlog(TuristAssistant.blogClient.getBlog(idBlog));
				} catch (RemoteException e1) {
					MessageBox dialog = new MessageBox(this.getShell(), this
							.getStyle()
							| SWT.ERROR | SWT.OK);
					dialog
							.setMessage("The server do not response. Be sure that a server's instance is running.");
					dialog.setText("Communication server error");
					dialog.open();
				}
				finish = true;
			}
		}
	}

	/**
	 * Des-selecciona el item activo.
	 */
	public void clearSelection() {
		active = null;
		enterButton.setEnabled(false);
		blogDescriptionLabel.setVisible(false);
		imageComposite.setBackgroundImage(null);
		update();
	}

}
